#include "watchdog_manager.h"
#include <unistd.h> // For sleep
#include <cstdlib>  // For system()
#include "utils_log.h"

namespace El {
namespace SystemService {

// 默认超时时间（秒）
static const int32_t DEFAULT_TIMEOUT_SECONDS = 20;

WatchdogManager &WatchdogManager::GetInstance()
{
    static WatchdogManager instance;
    return instance;
}

WatchdogManager::WatchdogManager() : timeoutSeconds_(DEFAULT_TIMEOUT_SECONDS), isRunning_(false)
{
    // 构造函数
}

WatchdogManager::~WatchdogManager()
{
    // 确保喂狗线程停止
    isRunning_.store(false, std::memory_order_release); // 通知线程停止
    if (feedThread_.joinable()) {
        feedThread_.join();
    }
}

bool WatchdogManager::Start()
{
    std::unique_lock<std::mutex> lock(mutex_);

    if (isRunning_.load(std::memory_order_acquire)) {
        isRunning_.store(false, std::memory_order_release);

        lock.unlock(); // 在join前解锁
        if (feedThread_.joinable()) {
            feedThread_.join();
        }
        lock.lock(); // join后重新锁定
        EL_INFO("Previous watchdog feed thread stopped for re-configuration.");
    }

    // 从配置中获取超时时间
    timeoutSeconds_ = DEFAULT_TIMEOUT_SECONDS;
    isRunning_.store(true, std::memory_order_release);

    if (feedThread_.joinable()) {
        // This case should ideally not be hit if the logic above is sound
        // but as a defensive measure.
        lock.unlock();
        feedThread_.join(); // Ensure any lingering thread is joined
        lock.lock();
    }
    feedThread_ = std::thread(&WatchdogManager::FeedThread, this);
    EL_INFO("Watchdog feed thread (re)started.");

    return true;
}

void WatchdogManager::FeedThread()
{
    EL_INFO("Watchdog feed thread running");

    int32_t currentTimeout;
    {
        std::lock_guard<std::mutex> lock(mutex_);
        currentTimeout = timeoutSeconds_;
    }

    int32_t feedInterval = currentTimeout / 3;
    if (feedInterval <= 0) {
        feedInterval = 1; // 至少1秒
    }
    EL_INFO("Watchdog feed interval: {} seconds", feedInterval);

    while (isRunning_.load(std::memory_order_acquire)) { // 循环直到 isRunning_ 为 false
        Feed();                                          // 直接调用 Feed，不再需要内部的 isRunning_ 检查

        // 休眠指定间隔，并在每次休眠后检查 isRunning_
        for (int32_t i = 0; i < feedInterval; ++i) {
            if (!isRunning_.load(std::memory_order_acquire)) { // 在长时间休眠中提前退出
                break;
            }
            sleep(1);
        }
    }
    EL_INFO("Watchdog feed thread exiting");
}

bool WatchdogManager::Feed()
{
    // 检查是否应运行 (原子读取)
    if (!isRunning_.load(std::memory_order_acquire)) {
        // EL_DEBUG("Watchdog not running (checked in Feed), skipping feed");
        return false;
    }

    // 使用 system 调用外部命令喂狗，并抑制其输出
    int ret = system("sample_wtdg -f > /dev/null 2>&1");
    if (ret != 0) {
        EL_DEBUG("Failed to feed watchdog using 'sample_wtdg -f'. Command returned: {}", ret);
        return false;
    }
    return true;
}

bool WatchdogManager::Stop()
{
    // 原子地设置 isRunning_ 为 false 并获取先前的值
    bool previously_running = isRunning_.exchange(false, std::memory_order_acq_rel);

    if (feedThread_.joinable()) {
        feedThread_.join(); // 等待线程结束
        EL_INFO("Watchdog feed thread joined.");
    }

    if (previously_running) {
        EL_INFO("Watchdog feeding process stopped.");
    } else {
        EL_INFO("Watchdog feeding process was already stopped or not active.");
    }
    return true;
}

bool WatchdogManager::IsRunning() const
{
    return isRunning_.load(std::memory_order_acquire); // 原子读取，无需互斥锁
}

int32_t WatchdogManager::GetTimeout() const
{
    std::lock_guard<std::mutex> lock(mutex_); // 保护 timeoutSeconds_
    return timeoutSeconds_;
}

} // namespace SystemService
} // namespace El